package com.seezoon.infrastructure.tcp.codec;

import io.netty.buffer.ByteBuf;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * JT808 消息，终端采用无符号byte/word/dword/GBK/byte[]
 */
@Getter
@Setter
@ToString
public class JTMessage {

    /**
     * 消息ID
     * 2字节
     */
    private int msgId;
    /**
     * 消息属性位定义（16位）：
     *
     * +------------------+------------+--------------------------------------------------+
     * | 位范围（从低到高） | 字段名      | 描述                                              |
     * +------------------+------------+--------------------------------------------------+
     * | 0-9             | bodyLength | 消息体长度（0-1023字节）                           |
     * | 10-12           | encryption | 000: 无加密, 001: RSA加密, 其他保留                |
     * | 13              | subpackage | 0: 不分包, 1: 分包                                 |
     * | 14-15           | reserved   | 保留（00）                                        |
     * +------------------+------------+--------------------------------------------------+
     *
     * 位掩码：
     * bodyLength  : 0x03FF (0000 0011 1111 1111)
     * encryption  : 0x1C00 (0001 1100 0000 0000) >> 10
     * subpackage  : 0x2000 (0010 0000 0000 0000) >> 13
     * reserved    : 0xC000 (1100 0000 0000 0000) >> 14
     */
    private int msgProperties;
    /**
     * SN编号，BCD编码
     * 6字节
     */
    private String serialNo;
    /**
     * 消息流水号，从0循环累加
     * 2字节
     */
    private int msgSerialNo;
    /**
     * 消息包封装项 (可选),取决于消息属性，包总数
     * 2字节
     */
    private int packageTotal;
    /**
     * 消息包封装项 (可选)，取决于消息属性，包编号，从1开始
     * 2字节
     */
    private int packageNo;
    /**
     * 消息体
     */
    private ByteBuf body;

    /**
     * 获取包体长度（低10位）
     *
     * @return
     */
    public int getBodyLength() {
        return msgProperties & 0x3FF;
    }

    public boolean hasSubPackage() {
        return (msgProperties & 0x2000) != 0;
    }

    public boolean needAuth() {
        return !(msgId == JT808.终端注册 || msgId == JT808.终端鉴权);
    }
}
